﻿using System;
using System.IO;
using System.Threading.Tasks;

namespace Core.Logger
{
    public enum LogLevel
    {
        Debug,
        Info,
        Warning,
        Error,
        Fatal
    }

    public static class Logger
    {
        private static readonly object _lock = new object();
        private static string _logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");
        private static bool _enableConsoleOutput = true;
        private static LogLevel _minimumLevel = LogLevel.Debug;

        static Logger()
        {
            // 确保日志目录存在
            if (!Directory.Exists(_logDirectory))
            {
                Directory.CreateDirectory(_logDirectory);
            }
        }

        /// <summary>
        /// 设置日志目录
        /// </summary>
        /// <param name="directory">日志目录路径</param>
        public static void SetLogDirectory(string directory)
        {
            _logDirectory = directory;
            if (!Directory.Exists(_logDirectory))
            {
                Directory.CreateDirectory(_logDirectory);
            }
        }

        /// <summary>
        /// 设置是否启用控制台输出
        /// </summary>
        /// <param name="enable">是否启用</param>
        public static void SetConsoleOutput(bool enable)
        {
            _enableConsoleOutput = enable;
        }

        /// <summary>
        /// 设置最小日志级别
        /// </summary>
        /// <param name="level">最小级别</param>
        public static void SetMinimumLevel(LogLevel level)
        {
            _minimumLevel = level;
        }

        /// <summary>
        /// 记录调试信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static void Debug(string message, Exception? exception = null)
        {
            WriteLog(LogLevel.Debug, message, exception);
        }

        /// <summary>
        /// 记录一般信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static void Info(string message, Exception? exception = null)
        {
            WriteLog(LogLevel.Info, message, exception);
        }

        /// <summary>
        /// 记录警告信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static void Warning(string message, Exception? exception = null)
        {
            WriteLog(LogLevel.Warning, message, exception);
        }

        /// <summary>
        /// 记录错误信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static void Error(string message, Exception? exception = null)
        {
            WriteLog(LogLevel.Error, message, exception);
        }

        /// <summary>
        /// 记录致命错误信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static void Fatal(string message, Exception? exception = null)
        {
            WriteLog(LogLevel.Fatal, message, exception);
        }

        /// <summary>
        /// 异步记录调试信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static async Task DebugAsync(string message, Exception? exception = null)
        {
            await WriteLogAsync(LogLevel.Debug, message, exception);
        }

        /// <summary>
        /// 异步记录一般信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static async Task InfoAsync(string message, Exception? exception = null)
        {
            await WriteLogAsync(LogLevel.Info, message, exception);
        }

        /// <summary>
        /// 异步记录警告信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static async Task WarningAsync(string message, Exception? exception = null)
        {
            await WriteLogAsync(LogLevel.Warning, message, exception);
        }

        /// <summary>
        /// 异步记录错误信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static async Task ErrorAsync(string message, Exception? exception = null)
        {
            await WriteLogAsync(LogLevel.Error, message, exception);
        }

        /// <summary>
        /// 异步记录致命错误信息
        /// </summary>
        /// <param name="message">日志消息</param>
        /// <param name="exception">异常信息（可选）</param>
        public static async Task FatalAsync(string message, Exception? exception = null)
        {
            await WriteLogAsync(LogLevel.Fatal, message, exception);
        }

        private static void WriteLog(LogLevel level, string message, Exception? exception)
        {
            if (level < _minimumLevel) return;

            var logEntry = FormatLogEntry(level, message, exception);

            lock (_lock)
            {
                try
                {
                    // 写入文件
                    var fileName = $"log_{DateTime.Now:yyyy-MM-dd}.txt";
                    var filePath = Path.Combine(_logDirectory, fileName);
                    File.AppendAllText(filePath, logEntry + Environment.NewLine);

                    // 控制台输出
                    if (_enableConsoleOutput)
                    {
                        Console.WriteLine(logEntry);
                    }
                }
                catch
                {
                    // 日志写入失败时不抛出异常，避免影响主程序
                }
            }
        }

        private static async Task WriteLogAsync(LogLevel level, string message, Exception? exception)
        {
            if (level < _minimumLevel) return;

            var logEntry = FormatLogEntry(level, message, exception);

            try
            {
                // 异步写入文件
                var fileName = $"log_{DateTime.Now:yyyy-MM-dd}.txt";
                var filePath = Path.Combine(_logDirectory, fileName);
                await File.AppendAllTextAsync(filePath, logEntry + Environment.NewLine);

                // 控制台输出
                if (_enableConsoleOutput)
                {
                    Console.WriteLine(logEntry);
                }
            }
            catch
            {
                // 日志写入失败时不抛出异常，避免影响主程序
            }
        }

        private static string FormatLogEntry(LogLevel level, string message, Exception? exception)
        {
            var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var threadId = Environment.CurrentManagedThreadId;
            var levelText = level.ToString().ToUpper().PadRight(7);

            var logEntry = $"[{timestamp}] [{threadId:D3}] [{levelText}] {message}";

            if (exception != null)
            {
                logEntry += Environment.NewLine + $"异常详情: {exception}";
            }

            return logEntry;
        }
    }
}